<script setup lang="ts">
//类定义
class Animal2 {
  name:string
  age:number
  constructor(name:string,age:number){
    this.name = name
    this.age = age
  }
  move(distanceInMeters: number):void{
    console.log(`${this.name} moved ${distanceInMeters}m.`)
  }
}
//继承
class Dog extends Animal2 {
  constructor(name:string,age:number){
    super(name,age) //super() 调用父类的构造函数
  }
  bark():void{
    console.log("Woof! Woof!")
  }
}
let dog = new Dog('dog',2)
dog.bark()
console.log(dog)



// 修饰符：TypeScript提供了几种访问修饰符来控制类的成员（属性和方法）的访问权限
/* 
public（默认）：成员可以在类的外部访问。
private：成员只能在类的内部访问。
protected：成员可以在类的内部和继承的子类中访问
*/
class Animal3 {
  private name:string
  protected age = 20
  constructor(name:string){
    this.name  = name
  }
  move(){
    console.log(`${this.name} move`);
  }
  protected getName(){
    console.log(this.name)
  }
}
const animal = new Animal3('tiger')
animal.move()
// console.log(animal.name)//属性“name”为私有属性，只能在类“Animal3”中访问
// animal.name = "cat"
// console.log(animal.name)

class Bird extends Animal3{
  constructor(name:string){
    super(name)//super() 调用父类的构造函数
  }
  getBirdName(){
    console.log(this.age)
    this.getName()
  }
}
const bird = new Bird("SmallBird")
bird.move()
bird.getBirdName()


// 存取器：TypeScript支持通过getters和setters来控制对对象成员的访问
//声明静态成员，它们属于类而不是类的实例
class Employee {
  static origin = { x: 0, y: 0 }//声明静态成员，它们属于类而不是类的实例
  private _fullName: string = "ab"

  get fullName(): string {
    return this._fullName
  }

  set fullName(newName: string) {
    if (newName && newName.length > 10) {
      this._fullName = newName
    } else {
      console.log("Name must be longer than 10 characters")
    }
  }
}
const employee1 = new Employee()
employee1.fullName = "Jos"
console.log("employee1.fullName: ", employee1.fullName)
// 静态属性
console.log(Employee.origin)


// 抽象类
// 定义抽象类 Shape
abstract class Shape {
  abstract area(): number // 抽象方法，没有具体实现
  // 具体方法
  describe(): string {
    return `形状的面积为: ${this.area()}`
  }
}
// 实现抽象类的子类 Circle
class Circle extends Shape {
  constructor(private radius: number) {
    super()
  }
 // 实现抽象方法
 area(): number {
    return Math.PI * Math.pow(this.radius, 2)
  }
}
// 使用
let circle = new Circle(5)
console.log(circle.describe())
// 输出: 形状的面积为: 78.53981633974483

</script>

<template>
</template>